package com.github.yingzhuo.spring.auto.datasource.composite.aop; import com.github.yingzhuo.spring.auto.datasource.composite.DataSourceConfig; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public abstract class DataSourceSwitchAdviceSupport { private final static Logger LOGGER = LoggerFactory.getLogger(DataSourceSwitchAdviceSupport.class); public Object around(ProceedingJoinPoint joinPoint) throws Throwable { DataSourceConfig annotation = findAnnotation(joinPoint, DataSourceConfig.class); if (annotation != null) { DataSourceRemoter remoter = DataSourceRemoter.getInstance(); remoter.set(annotation.value()); LOGGER.debug("数据源设置: name={}", annotation.value()); } else { LOGGER.debug("数据源设置: name=<default>"); } return joinPoint.proceed(); } /* * 反射获得标注 查找顺序如下 * 1. 实现类上方法 * 2. 实现类类型 * 3. 接口方法上 * 4. 接口类型 */ private <T extends Annotation> T findAnnotation(ProceedingJoinPoint joinPoint, Class<T> annotationType) throws Throwable { final Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); final Class<?> implCls = joinPoint.getTarget().getClass(); T anno; Method implMethod = implCls.getMethod(method.getName(), method.getParameterTypes()); anno = implMethod.getDeclaredAnnotation(annotationType); if (anno != null) { return anno; } anno = implCls.getAnnotation(annotationType); if (anno != null) { return anno; } Class<?>[] interfaces = implCls.getInterfaces(); for (Class<?> interfaceCls : interfaces) { Method ifaceMethod; try { ifaceMethod = interfaceCls.getMethod(method.getName(), method.getParameterTypes()); } catch (NoSuchMethodException e) { continue; } catch (SecurityException e) { continue; } anno = ifaceMethod.getAnnotation(annotationType); if (anno != null) { return anno; } anno = interfaceCls.getAnnotation(annotationType); if (anno != null) { return anno; } } return null; } }